/*!
 Temelia - Queue performance tests.

 Copyright (C) 2008 Ceata (http://cod.ceata.org/proiecte/temelia).

 @author Dascalu Laurentiu

 This program is free software; you can redistribute it and
 modify it under the terms of the GNU General Public License
 as published by the Free Software Foundation; either version 3
 of the License, or (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

#include "include/performance.hpp"
#include "include/testutil.hpp"
#include <queue>

extern "C"
{
#include <temelia/queue.h>
}

// temelia
static void temelia_queue_push_front(int n)
{
	queue_t temelia_queue = queue_new(n);

	for (int i = 0; i < n; i++)
		queue_push_back(temelia_queue, &i);

	queue_delete(temelia_queue);
}

static void temelia_queue_push_back(int n)
{
	queue_t temelia_queue = queue_new(n);

	for (int i = 0; i < n; i++)
		queue_push_back(temelia_queue, &i);

	queue_delete(temelia_queue);
}

static void temelia_queue_pop_front(int n)
{
	queue_t temelia_queue = queue_new(n);

	for (int i = 0; i < n; i++)
		queue_push_front(temelia_queue, &i);

	while (!queue_is_empty(temelia_queue))
		queue_pop_front(temelia_queue);

	queue_delete(temelia_queue);
}

static void temelia_queue_pop_back(int n)
{
	queue_t temelia_queue = queue_new(n);

	for (int i = 0; i < n; i++)
		queue_push_back(temelia_queue, &i);

	while (!queue_is_empty(temelia_queue))
		queue_pop_back(temelia_queue);

	queue_delete(temelia_queue);
}

static void my_temelia_key_handler(void *key, void *context)
{

}

static void temelia_queue_iterate(int n)
{
	queue_t temelia_queue = queue_new(n);

	for (int i = 0; i < n; i++)
		queue_push_back(temelia_queue, &i);

	queue_iterate(temelia_queue, my_temelia_key_handler, NULL, 1);
	queue_delete(temelia_queue);
}

// STL
static void stl_queue_push_back(int n)
{
	std::queue<int *> stl_queue;

	for (int i = 0; i < n; i++)
		stl_queue.push(&i);
}

static void stl_queue_pop_front(int n)
{
	std::queue<int *> stl_queue;

	for (int i = 0; i < n; i++)
		stl_queue.push(&i);

	while (!stl_queue.empty())
		stl_queue.pop();
}

static void my_stl_key_handler(int *key, void *context)
{

}

static void stl_queue_iterate(int n)
{
	std::queue<int *> stl_queue;

	for (int i = 0; i < n; i++)
		stl_queue.push(&i);

	while (!stl_queue.empty())
	{
		my_stl_key_handler(stl_queue.front(), NULL);
		stl_queue.pop();
	}
}

void TemeliaPerformance::pt_queue(void)
{
	TestUnit testUnit("queue");

	GENERATE_TEMELIA_TEST(testUnit, "push_back", queue_push_back);
	GENERATE_TEMELIA_TEST(testUnit, "push_front", queue_push_front);
	GENERATE_TEMELIA_TEST(testUnit, "pop_back", queue_pop_back);
	GENERATE_TEMELIA_TEST(testUnit, "pop_front", queue_pop_front);
	GENERATE_TEMELIA_TEST(testUnit, "iterate", queue_iterate);

	GENERATE_STL_TEST(testUnit, "push_back", queue_push_back);
	GENERATE_STL_TEST(testUnit, "pop_front", queue_pop_front);
	GENERATE_STL_TEST(testUnit, "iterate", queue_iterate);

	testUnit.write(fout);
}
